package locations.dao.implement;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import locations.dao.GenericDAO;

public class GenericDAOHibernateJPA<T> implements GenericDAO<T>{
	protected Class<T> type;
	protected EntityManager entityManager;
	protected EntityTransaction transaction;
	protected CriteriaBuilder criteriaBuilder;

	public GenericDAOHibernateJPA() {
		super();
		this.entityManager = Persistence.createEntityManagerFactory("locations").createEntityManager();
		this.transaction = entityManager.getTransaction();
		this.criteriaBuilder = entityManager.getCriteriaBuilder();
	}
	public GenericDAOHibernateJPA(Class<T> type)
	{
		this();
		this.type = type;
	}
	

	public T save(T o) {
		this.getTransaction().begin();
		T entity = this.getEntityManager().merge(o);
		this.getTransaction().commit();
		return entity;
	}

	public T delete(long id) {
		this.getTransaction().begin();
		T entity = this.getEntityManager().find(this.getType(), id);
		this.getEntityManager().remove(entity);
		this.getEntityManager().close();
		this.getTransaction().commit();
		return entity;
	}

	public List<T> retrieveAll() {
		this.getTransaction().begin();
		CriteriaQuery q = criteriaBuilder.createQuery();
		Root<T> c = q.from(type);
		q.select(c);
		TypedQuery<T> query = this.getEntityManager().createQuery(q);
		List<T>list = query.getResultList();
		this.getTransaction().commit();
		return list;
	}

	public T retrieveById(long id) {
		this.getTransaction().begin();
		T entity = this.getEntityManager().find(this.getType(), id);
		this.getTransaction().commit();
		return entity;
	}
	public Class<T> getType() {
		return type;
	}

	public void setType(Class<T> type) {
		this.type = type;
	}

	public EntityManager getEntityManager() {
		return entityManager;
	}

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	public EntityTransaction getTransaction() {
		return transaction;
	}

	public void setTransaction(EntityTransaction transaction) {
		this.transaction = transaction;
	}

	public CriteriaBuilder getCriteriaBuilder() {
		return criteriaBuilder;
	}

	public void setCriteriaBuilder(CriteriaBuilder criteriaBuilder) {
		this.criteriaBuilder = criteriaBuilder;
	}
}
